#define  _CAN_TO_UART_GLOBAL_
#include "config.h"

void sendMsgToExt(U8 cmdID,U8 *pData, U8 len)
{
	U8 checkSum;
	FIFO_PUT_ONE(Uart2TxFifo,0xFF);
	FIFO_PUT_ONE(Uart2TxFifo,0x55);
	FIFO_PUT_ONE(Uart2TxFifo,(u8)(len+1));
	checkSum = len+1;
	checkSum += cmdID;
	FIFO_PUT_ONE(Uart2TxFifo,cmdID);
	while (len)
	{
		checkSum += *pData;
		FIFO_PUT_ONE(Uart2TxFifo,*pData);
		len--;
		pData++;
	}
	FIFO_PUT_ONE(Uart2TxFifo,checkSum);
	activeUart2Send();
}

void sendActivePingToExt(void)
{
	U8 sendBuff[] = {0x00,0x04,0x03,0x02,0x01};
	sendMsgToExt(0xC9,sendBuff,sizeof(sendBuff));
}

void sendPingToExt(void)
{
	U8 sendBuff[] = {0x00,0x05,0x06,0x07,0x08};
	sendMsgToExt(0xC9,sendBuff,sizeof(sendBuff));
}
//combo:4byteID+1byteType+NByteData
void sendCanMsgToExt(CanTxMsg *pCanTxMsg)
{
	U8 sendBuff[4+1+8];
	if (pCanTxMsg->DLC > 8)
	{
		return;
	}
	if (pCanTxMsg->IDE == CAN_ID_EXT)
	{
		memcpy(&sendBuff[0],&pCanTxMsg->ExtId,4);
		sendBuff[4] = 0x80;
	}
	else
	{
		memcpy(&sendBuff[0],&pCanTxMsg->StdId,4);
		sendBuff[4] = 0x00;
	}
	if (pCanTxMsg->RTR == CAN_RTR_REMOTE)
	{
		sendBuff[4] |= 0x40;
	}
	sendBuff[4] |= pCanTxMsg->DLC;
	memcpy(&sendBuff[5],pCanTxMsg->Data,pCanTxMsg->DLC);
	sendMsgToExt(0xCA,sendBuff,4+1+pCanTxMsg->DLC);
}

void dealCANExtMsg(U8 *pData,U8 len)
{
	switch (pData[0])
	{
		case 0xCA:
			{
				U32 canID;
				CanTxMsg canTxMsg;
				if (pData[5] & 0x80)
				{
					canTxMsg.IDE = CAN_ID_EXT;
					memcpy(&canID,&pData[1],4);
					canTxMsg.ExtId = canID;
				}
				else
				{
					canTxMsg.IDE = CAN_ID_STD;
					memcpy(&canID,&pData[1],4);
					canTxMsg.StdId = canID;
				}
				if (pData[5] & 0x40)
				{
					canTxMsg.RTR = CAN_RTR_REMOTE;
				}
				else
				{
					canTxMsg.RTR = CAN_RTR_DATA;
				}
				canTxMsg.DLC = pData[5] & 0x0F;
				memcpy(canTxMsg.Data,&pData[6],canTxMsg.DLC);
				if (0 == canID % 3)
				{
					FIFO_PUT_ONE(CanTx0Fifo,canTxMsg);
				}
				else if (1 == canID % 3)
				{
					FIFO_PUT_ONE(CanTx1Fifo,canTxMsg);
				}
				else
				{
					FIFO_PUT_ONE(CanTx2Fifo,canTxMsg);
				}
				CANFrameSendProc();
			}
			break;
		case 0xC9:
			if (0x00 == pData[1])
			{
				sendPingToExt();
			}
			break;			
		default:
			break;
	}
}

void CANToUARTMsgDataProc(U8 data)
{
	switch (CANToUARTInfo.frameCMDStatus)
	{
		case 0:
			if (0xFF == data)
			{
				CANToUARTInfo.frameCMDStatus = 1;
			}
			break;
		case 1:
			if (0x55 == data)
			{
				CANToUARTInfo.frameCMDStatus = 2;
			}
			else if (0xFF == data)
			{
				CANToUARTInfo.frameCMDStatus = 1;
			}
			else
			{
				CANToUARTInfo.frameCMDStatus = 0;
			}
			break;
		case 2:
			CANToUARTInfo.frameCMDMsgCRC = data;
			CANToUARTInfo.frameCMDMsgLengthMax = data;
			CANToUARTInfo.frameCMDMsgLengthNow = 0;
			CANToUARTInfo.frameCMDStatus = 3;
			break;
		case 3:
			if (CANToUARTInfo.frameCMDMsgLengthNow < CANToUARTInfo.frameCMDMsgLengthMax)
			{
				CANToUARTInfo.frameCMDMsgBuff[CANToUARTInfo.frameCMDMsgLengthNow++] = data;
				CANToUARTInfo.frameCMDMsgCRC += data;
			}
			else
			{
				if (CANToUARTInfo.frameCMDMsgCRC == data)
				{
					CANToUARTInfo.crcSuccessCount++;
					dealCANExtMsg(CANToUARTInfo.frameCMDMsgBuff,CANToUARTInfo.frameCMDMsgLengthMax);
				}
				else
				{
					CANToUARTInfo.crcFailCount++;
					printf("CANToUARTMsgDataProc CRC Error! \r\n");
				}
				CANToUARTInfo.frameCMDStatus = 0;
			}
			break;
		default:
			CANToUARTInfo.frameCMDStatus = 0;
			break;
	}
}

void CANToUARTProccessor(void)
{
	ReadUart2DataUsingDMA();
	CANFrameSendProc();
	if (GetTickCount() - CANToUARTInfo.sendActivePingTime >= T_1S)
	{
		CANToUARTInfo.sendActivePingTime = GetTickCount();
		sendActivePingToExt();
	}
}

void CANToUARTInit(void)
{
	memset(&CANToUARTInfo,0,sizeof(CAN_TO_UART_INFO));
	Uart2Init(1000000);
}


